'use client';

import {
  type ChangeEvent,
  type FormEvent,
  useContext,
  useEffect,
  useState,
} from 'react';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import diff from 'microdiff';
import type {
  IConfigCaptchaItem,
  IConfigImage,
  IDifference,
  IUpdateImageConfigBody,
} from '@/interfaces';
import type { IConfigImageContentType, TBody } from '@/types';
import { updateImageConfig } from '@/services/api';
import classNames from 'classnames';
import useToast from '@/hooks/useToast';
import { ConfigAdminContext } from '@/contexts/admin/config';
import { getDiffData, getFilterData, isEmpty } from '@/lib/tool';

export default function UpdateConfigImage(
  this: any,
  {
    details,
  }: {
    details: IConfigImage;
  },
) {
  const context = useContext(ConfigAdminContext);
  const [tabIndex, setTabIndex] = useState(1);

  function onClickTab(index: number) {
    setTabIndex(index);
  }

  return (
    <div className="row">
      <div className="col">
        <div className="vstack gap-4">
          <nav className="nav nav-pills flex-column flex-sm-row">
            <a
              onClick={onClickTab.bind(this, 1)}
              className={classNames(
                'flex-sm-fill text-sm-center nav-link cursor-pointer',
                {
                  'bg-light': tabIndex === 1,
                },
              )}
            >
              登录
            </a>
            <a
              onClick={onClickTab.bind(this, 2)}
              className={classNames(
                'flex-sm-fill text-sm-center nav-link cursor-pointer',
                {
                  'bg-light': tabIndex === 2,
                },
              )}
            >
              注册
            </a>
            <a
              onClick={onClickTab.bind(this, 3)}
              className={classNames(
                'flex-sm-fill text-sm-center nav-link cursor-pointer',
                {
                  'bg-light': tabIndex === 3,
                },
              )}
            >
              验证
            </a>
          </nav>

          {tabIndex === 1 && <FormItem type="LOGIN" details={details} />}

          {tabIndex === 2 && <FormItem type="REGISTER" details={details} />}

          {tabIndex === 3 && <FormItem type="VERIFY" details={details} />}
        </div>
      </div>
    </div>
  );
}

const FormItem = ({
  type,
  details,
}: {
  type: IConfigImageContentType;
  details: IConfigImage;
}) => {
  const { show } = useToast();
  const context = useContext(ConfigAdminContext);
  const [form, setForm] = useState<IConfigCaptchaItem>({
    enable: false,
    expire: 'PT5M',
    total: 5,
    interval: 'PT1M',
    recoveryTime: 'PT24H',
    length: 4,
    alphanumeric: false,
    alphabetic: false,
    ascii: false,
    numeric: true,
  });
  const [differenceData, setDifferenceData] = useState<IDifference[]>([]);
  const queryClient = useQueryClient();

  const updateImageConfigMutation = useMutation(
    async (variables: TBody<IUpdateImageConfigBody>) => {
      await updateImageConfig(variables);
      await queryClient.invalidateQueries([
        '/configs',
        `/${context.updateItem?.id}`,
      ]);
    },
  );

  useEffect(() => {
    if (details) {
      const captchaConfig = details.list[type]?.captchaConfig;
      if (captchaConfig) {
        setForm({ ...form, ...captchaConfig });
      }
    }
  }, [details]);
  useEffect(() => {
    if (details) {
      let data = {};
      const captchaConfig = details.list[type]?.captchaConfig;
      if (captchaConfig) {
        data = captchaConfig;
      }

      const differences = diff(data, form);
      setDifferenceData(differences);
    }
  }, [form, details]);

  function onChangeForm(
    e: ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>,
  ) {
    const name = e.target.name;
    const value = e.target.value;

    if (
      name === 'enable' ||
      name === 'alphanumeric' ||
      name === 'alphabetic' ||
      name === 'ascii' ||
      name === 'numeric'
    ) {
      setForm({
        ...form,
        [name]: value === 'true',
      });
    } else if (name === 'total' || name === 'length') {
      setForm({
        ...form,
        [name]: parseInt(value),
      });
    } else {
      setForm({
        ...form,
        [name]: value,
      });
    }
  }

  async function onClickSave(e: FormEvent<HTMLFormElement>) {
    try {
      e.preventDefault();
      e.stopPropagation();

      const body = getFilterData(getDiffData(differenceData));
      if (isEmpty(body)) {
        show({
          type: 'SUCCESS',
          message: '保存完成',
        });
        return;
      }

      await updateImageConfigMutation.mutateAsync({
        data: {
          list: {
            [type]: body,
          },
        },
      });

      clearData();
      show({
        type: 'SUCCESS',
        message: '保存完成',
      });
    } catch (e) {
      updateImageConfigMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    }
  }

  function clearData() {
    setDifferenceData([]);
  }

  return (
    <form onSubmit={onClickSave} className="vstack gap-4">
      <div>
        <label className="form-label">是否启用</label>
        <select
          name="enable"
          value={form.enable ? 'true' : 'false'}
          onChange={onChangeForm}
          className="form-select"
          aria-label="enable"
          placeholder="请选择验证码是否启用"
        >
          <option value="true">true</option>
          <option value="false">false</option>
        </select>
      </div>

      <div>
        <label className="form-label">
          有效期
          <span className="text-muted">（H 小时，M 分钟，S 秒）</span>
        </label>
        <input
          type="text"
          className="form-control"
          name="expire"
          value={form.expire}
          onChange={onChangeForm}
          aria-describedby="expire"
          placeholder="请输入验证码有效期"
        />
      </div>

      <div>
        <label className="form-label">有效次数</label>
        <input
          min={1}
          type="number"
          className="form-control"
          name="total"
          value={form.total}
          onChange={onChangeForm}
          aria-describedby="total"
          placeholder="请输入验证码有效次数"
        />
      </div>

      <div>
        <label className="form-label">
          间隔时间
          <span className="text-muted">（H 小时，M 分钟，S 秒）</span>
        </label>
        <input
          type="text"
          className="form-control"
          name="interval"
          value={form.interval}
          onChange={onChangeForm}
          aria-describedby="interval"
          placeholder="请输入验证码间隔时间"
        />
      </div>

      <div>
        <label className="form-label">
          次数恢复时间
          <span className="text-muted">（H 小时，M 分钟，S 秒）</span>
        </label>
        <input
          type="text"
          className="form-control"
          name="recoveryTime"
          value={form.recoveryTime}
          onChange={onChangeForm}
          aria-describedby="recoveryTime"
          placeholder="请输入验证码次数恢复时间"
        />
      </div>

      <div>
        <label className="form-label">长度</label>
        <input
          min={1}
          type="number"
          className="form-control"
          name="length"
          value={form.length}
          onChange={onChangeForm}
          aria-describedby="length"
          placeholder="请输入验证码长度"
        />
      </div>

      <div>
        <label className="form-label">字母数字</label>
        <select
          name="alphanumeric"
          value={form.alphanumeric ? 'true' : 'false'}
          onChange={onChangeForm}
          className="form-select"
          aria-label="alphanumeric"
          placeholder="请选择验证码是否为字母数字"
        >
          <option value="true">true</option>
          <option value="false">false</option>
        </select>
      </div>

      <div>
        <label className="form-label">字母</label>
        <select
          name="alphabetic"
          value={form.alphabetic ? 'true' : 'false'}
          onChange={onChangeForm}
          className="form-select"
          aria-label="alphabetic"
          placeholder="请选择验证码是否为字母"
        >
          <option value="true">true</option>
          <option value="false">false</option>
        </select>
      </div>

      <div>
        <label className="form-label">ascii</label>
        <select
          name="ascii"
          value={form.ascii ? 'true' : 'false'}
          onChange={onChangeForm}
          className="form-select"
          aria-label="ascii"
          placeholder="请选择验证码是否为 ascii"
        >
          <option value="true">true</option>
          <option value="false">false</option>
        </select>
      </div>

      <div>
        <label className="form-label">数字</label>
        <select
          name="numeric"
          value={form.numeric ? 'true' : 'false'}
          onChange={onChangeForm}
          className="form-select"
          aria-label="numeric"
          placeholder="请选择验证码是否为数字"
        >
          <option value="true">true</option>
          <option value="false">false</option>
        </select>
      </div>

      <button
        type="submit"
        disabled={updateImageConfigMutation.isLoading}
        className="btn btn-success w-25 my-4"
      >
        {updateImageConfigMutation.isLoading && (
          <span
            className="spinner-border spinner-border-sm me-2"
            role="status"
            aria-hidden="true"
          ></span>
        )}
        更新
      </button>
    </form>
  );
};
